/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arg.deploy.webapp.add.ctrl;

import com.arg.deploy.bean.ErrorItem;
import com.arg.deploy.bean.Tag;
import com.arg.deploy.bean.TagLookupCatalog;
import com.arg.deploy.bean.User;
import com.arg.deploy.bean.ValidateBean;
import com.arg.deploy.common.FileUtil;
import com.arg.deploy.common.GenScript;
import com.arg.deploy.common.TextFileReaderUtil;
import com.arg.deploy.core.hibernate.TagCore;
import com.arg.deploy.core.hibernate.TagLookupCatalogCore;
import com.arg.deploy.core.hibernate.UserCore;
import com.arg.deploy.webapp.attribute.FileAttribute;
import com.arg.deploy.webapp.common.AlertMessages;
import com.arg.deploy.webapp.common.ComboboxUtil;
import com.arg.deploy.webapp.common.MainPageController;
import com.arg.deploy.webapp.common.ResourceUtil;
import com.arg.deploy.webapp.common.ValidateManager;
import com.arg.deploy.webapp.common.ValidateUtil;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Radiogroup;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.Textbox;

/**
 *
 * @author sorasaks
 */
public class AddTagHotFixCtrl extends MainPageController {

    public static final String TAG_HOTFIX = "HOTFIX";
    private static final Logger LOG = Logger.getLogger(AddTagHotFixCtrl.class);
    private Label lbTotal;
    private Radiogroup radioTagType;
    private Textbox txtSearch;
    private Textbox txtTagText;
    private Textbox txtTagIssue;
    private Textbox txtTagAuthor;
    private List<String> header = new ArrayList<String>();
    private Combobox cbbHeader;
    private Button btnSearch;
    private Button btnReload;
    private Button btnGenerate;
    private Button btnAdd;
    private Button btnDel;
    private Button btnSave;
    private Grid gridTag;
    private AddTagHotFixRenderer renderer;
    private Checkbox chkAll;
    private List<Tag> searchObject;
    private TagLookupCatalog catalog;

    public AddTagHotFixCtrl() {
        super("default.message.title.addtag.release", Boolean.TRUE);
    }

    @Override
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp); //To change body of generated methods, choose Tools | Templates.
        initialComponent();
        initialCombobox();
        initialRenderer();
        initialEventListener();
    }

    private void initialComponent() {
        cbbHeader.setDisabled(true);
        catalog = TagLookupCatalogCore.getLookupByName(TAG_HOTFIX);

        if (catalog == null) {
            AlertMessages.alertMessage("ผิดพลาด ::: Tag Type ไม่ถูกต้องกรุณาตรวจสอบ");
            throw new NullPointerException();
        }
    }

    private void initialCombobox() {

        File file = new File(FileAttribute.SETTING_TAG_MONITOR_FILE);
        LOG.info(file.getAbsolutePath());

        if (!file.exists()) {
            FileUtil.createFile(FileAttribute.SETTING_TAG_MONITOR_FILE, new StringBuilder(""));
        }

        generateSettingFile();

        Collections.reverse(header);
        ComboboxUtil.buildCombobox(cbbHeader, header, cbbHeader.getText());
    }

    private void generateSettingFile() {
        List<String> allSetting = TextFileReaderUtil.read(FileAttribute.SETTING_TAG_MONITOR_FILE);
        header = new ArrayList<String>();

        if (!allSetting.isEmpty()) {
            for (String s : allSetting) {
                String[] setting = s.trim().split("=");
                if (setting[0].equals("HEADER")) {
                    header.add(setting[1]);
                }
            }
        }
    }

    private void appendSettingFile() {

        if (!header.contains(cbbHeader.getText())
                && !StringUtils.isEmpty(cbbHeader.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_MONITOR_FILE, "HEADER=" + (cbbHeader.getText()).trim());
        }
        System.out.println("header = " + header.contains(cbbHeader.getText()));
        System.out.println("cbbHeader = " + cbbHeader.getText());

        initialCombobox();
    }

    private void initialEventListener() {
        btnSave.addEventListener(Events.ON_CLICK, new SaveTagRendererEventListener());
        btnAdd.addEventListener(Events.ON_CLICK, new AddTagRendererEventListener());
        btnDel.addEventListener(Events.ON_CLICK, new DelTagRendererEventListener());
        btnSearch.addEventListener(Events.ON_CLICK, new SearchTagRendererEventListener());
        btnReload.addEventListener(Events.ON_CLICK, new ReloadTagRendererEventListener());
        btnGenerate.addEventListener(Events.ON_CLICK, new GenerateTag());
        radioTagType.addEventListener(Events.ON_CHECK, new RadioTypeChoose());
        txtSearch.addEventListener(Events.ON_OK, new SearchTagRendererEventListener());
    }

    private void initialRenderer() {
        renderer = new AddTagHotFixRenderer(chkAll, gridTag);
        gridTag.setRowRenderer(renderer);
        doSearch(null);
    }

    private class ReloadTagRendererEventListener implements EventListener {

        public ReloadTagRendererEventListener() {
        }

        @Override
        public void onEvent(Event t) throws Exception {
            doSearch(null);
        }
    }

    private class RadioTypeChoose implements EventListener {

        public RadioTypeChoose() {
        }

        @Override
        public void onEvent(Event t) throws Exception {
            if (((String) radioTagType.getSelectedItem().getValue()).equals(GenScript.TAG_TYPE_VERSION_CONTROL)) {
                cbbHeader.setDisabled(true);
            } else if (((String) radioTagType.getSelectedItem().getValue()).equals(GenScript.TAG_TYPE_NORMAL)) {
                cbbHeader.setDisabled(false);
            }
        }
    }

    private class GenerateTag implements EventListener {

        public GenerateTag() {
        }

        @Override
        public void onEvent(Event t) throws Exception {

            appendSettingFile();

            if (!validateGenerate()) {
                return;
            }

            List<Tag> listTag = GenScript.generate(txtTagText.getValue(), (String) radioTagType.getSelectedItem().getValue(), cbbHeader.getText());
            LOG.info("::::::::::::::::::::::::::::: listTag = " + listTag.size());

//            User user = UserCore.getUserByUsername(txtTagAuthor.getValue());
//            if (user == null) {
//                ValidateManager vm = new ValidateManager();
//                vm.add(ValidateUtil.addError(txtTagAuthor, "ผิดพลาด ::: Author ไม่ถูกต้อง"));
//                AlertMessages.alertMessage(vm.getMessageTemplate());
//                return;
//            }

//            for (Tag tag : listTag) {
//                tag.setTag(catalog);
//                tag.setUser(user);
//                tag.setIssue(txtTagIssue.getValue().toUpperCase());
//                tag.setCreateDate(new Date());
//                Boolean isSave = TagCore.save(tag, userByLogin);
//                
//                if (!isSave) {
//                    AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.failed.save", locale));
//                    break;
//                }
//            }

            ValidateBean validate = TagCore.saveList(listTag, catalog, txtTagAuthor.getValue(), txtTagIssue.getValue().toUpperCase(), userByLogin);
            if (!validate.getStatus()) {
                for (ErrorItem error : validate.getErrorList()) {
                    AlertMessages.alertMessage(error.getMessage());
                }
                return;
            }
            
            AlertMessages.alertMessage("บันทึกข้อมูลสำเร็จ");
            
            List<Tag> listTagSearch = TagCore.getTag(txtTagIssue.getValue(), userByLogin, catalog, null, null);
            LOG.info("::::::::::::::::::::: listTagSearch.size() = " + listTagSearch.size());

            if (listTagSearch.isEmpty()) {
                AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.no.data", locale));
            }

            doSearch(listTagSearch);
        }
    }

    private class SaveTagRendererEventListener implements EventListener {

        public SaveTagRendererEventListener() {
        }

        @Override
        public void onEvent(Event t) throws Exception {
            if (!validateSave()) {
                return;
            }

            ListModelList listM = (ListModelList) gridTag.getModel();
            List<Object> testTemplateList = listM.getInnerList();
            List<Tag> tagList = new ArrayList<Tag>();
            for (Object o : testTemplateList) {
                Tag tag = (Tag) o;

//                User user = UserCore.getUserByUsername(tag.getUsername());
                tag.setTag(catalog);
//                tag.setUser(user);
                tag.setIssue(tag.getIssue().toUpperCase());

//                LOG.info(":::::::::::::::::::::::: user = " + user);

                String filename = tag.getPath().split("/")[tag.getPath().split("/").length - 1];
                tag.setFilename(filename);
                tag.setCreateDate(new Date());

                LOG.info(":::::::::::::::::::::::: tag = " + tag);

                tagList.add(tag);
//                Boolean isSave = TagCore.save(tag, userByLogin);
//                if (!isSave) {
//                    AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.failed.save", locale));
//                    return;
//                }
            }

            ValidateBean validate = TagCore.saveList(tagList, userByLogin);
            if (!validate.getStatus()) {
                for (ErrorItem error : validate.getErrorList()) {
                    AlertMessages.alertMessage(error.getMessage());
                }
                return;
            }

            AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.save", locale));
            
            List<Tag> listTagSearch = TagCore.getTag(txtSearch.getValue(), userByLogin, catalog, null, null);
            LOG.info("::::::::::::::::::::: listTagSearch.size() = " + listTagSearch.size());

            if (listTagSearch.isEmpty()) {
                AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.no.data", locale));
            }

            doSearch(listTagSearch);
        }
    }

    private class AddTagRendererEventListener implements EventListener {

        public AddTagRendererEventListener() {
        }

        @Override
        public void onEvent(Event t) throws Exception {
            if (!validateSave()) {
                return;
            }

            ListModelList listM = (ListModelList) gridTag.getListModel();
            List<Tag> list = listM.getInnerList();

            if (list == null) {
                list = new ArrayList<Tag>();
            }
            Tag tag = new Tag();
            tag.setMode("MODIFY");
            tag.setUser(userByLogin);
            list.add(0, tag);

            doSearch(list);
        }
    }

    private class DelTagRendererEventListener implements EventListener {

        public DelTagRendererEventListener() {
        }

        @Override
        public void onEvent(Event t) throws Exception {

            if (renderer.getCheckedSizeOfCheckbox() <= 0) {
                AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.validate", locale));
                return;
            }

            if (AlertMessages.NO == AlertMessages.confirmMessage("คุณต้องการลบข้อมูลใช่หรือไหม่?")) {
                return;
            }

            List<Tag> selectListValue = (List) renderer.selectTemplateList;
            List<Checkbox> selectListCheckbox = (List) renderer.selectTemplateCheckboxList;

            Tag tagClound = null;

            Boolean isBreak = Boolean.FALSE;
            for (Tag tag : selectListValue) {
                LOG.info(":::::::::::::::::::::::: tag = " + tag);
                Boolean isRemove = Boolean.FALSE;
                if (tag != null
                        && tag.getId() != null) {
                    isRemove = Boolean.TRUE;
                }
                if (isRemove) {
                    Boolean isSuccess = TagCore.remove(tag);
                    if (!isSuccess) {
                        tagClound = tag;
                        isBreak = Boolean.TRUE;
                        break;
                    }
                }
                Checkbox chkbox = selectListCheckbox.get(selectListValue.indexOf(tag));
                renderer.removeRow(chkbox);
            }

            if (isBreak && tagClound != null) {
                AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.failed.delete", locale));
            }

            AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.delete.success", locale));

            doSearch(null);

        }
    }

    private class SearchTagRendererEventListener implements EventListener {

        public SearchTagRendererEventListener() {
        }

        @Override
        public void onEvent(Event t) throws Exception {
            List<Tag> listTag = TagCore.getTag(txtSearch.getValue(), userByLogin, catalog, null, null);
            LOG.info("::::::::::::::::::::: listTag.size() = " + listTag.size());

            if (listTag.isEmpty()) {
                AlertMessages.alertMessage(ResourceUtil.getLabel("default.alert.message.no.data", locale));
            }

            doSearch(listTag);
        }
    }

    private Boolean validateGenerate() {
        ValidateManager vm = new ValidateManager();

        vm.add(ValidateUtil.requireField(txtTagText));
        vm.add(ValidateUtil.requireField(txtTagIssue));
        vm.add(ValidateUtil.requireField(txtTagAuthor));

        if (((String) radioTagType.getSelectedItem().getValue()).equals(GenScript.TAG_TYPE_NORMAL)) {
            vm.add(ValidateUtil.requireField(cbbHeader));
        }

        if (!vm.getValue()) {
            AlertMessages.alertMessage(vm.getMessageTemplate());
        }

        return vm.getValue();
    }

    private Boolean validateSave() throws UnsupportedEncodingException {
        List<Row> listRow = renderer.getRowRenderer();
        HashMap paramValue = renderer.getRowComponent();

        LOG.info(":::::::::::::::::::::::::: listRow.size() = " + listRow.size());

        ValidateManager vm = new ValidateManager();
        for (Row row : listRow) {
            List<Component> listComp = (List<Component>) paramValue.get(row);
            Combobox txtMode = (Combobox) listComp.get(2);
            Textbox txtIssue = (Textbox) listComp.get(3);
            Textbox txtRevision = (Textbox) listComp.get(4);
            Textbox txtPath = (Textbox) listComp.get(5);
            Textbox txtAuthor = (Textbox) listComp.get(6);

            vm.add(ValidateUtil.requireField(txtMode));
            vm.add(ValidateUtil.requireField(txtIssue));
            vm.add(ValidateUtil.requireField(txtRevision));
            vm.add(ValidateUtil.requireField(txtPath));
            vm.add(ValidateUtil.requireField(txtAuthor));

            if (!vm.getValue()) {
                AlertMessages.alertMessage(vm.getMessageTemplate());
                return Boolean.FALSE;
            }

            String[] reversion = txtRevision.getValue().replace(".", ",").split(",");
            if (!(reversion.length == 2
                    || reversion.length == 4)) {
                vm.add(ValidateUtil.addError(txtRevision, ResourceUtil.getLabel("default.alert.message.invalid.revision", locale)));
                AlertMessages.alertMessage(vm.getMessageTemplate());
                return Boolean.FALSE;
            }

            if (txtPath.getValue().split("/").length <= 1) {
                vm.add(ValidateUtil.addError(txtPath, ResourceUtil.getLabel("default.alert.message.invalid.path", locale)));
                AlertMessages.alertMessage(vm.getMessageTemplate());
                return Boolean.FALSE;
            }

            User user = UserCore.getUserByUsername(txtAuthor.getValue());
            if (user == null) {
                vm.add(ValidateUtil.addError(txtAuthor, ResourceUtil.getLabel("default.alert.message.invalid.author", locale)));
                AlertMessages.alertMessage(vm.getMessageTemplate());
                return Boolean.FALSE;
            }
        }
        return Boolean.TRUE;
    }

    private void doSearch(List list) {
//        txtSearch.setRawValue(null);
        if (list == null) {
            if (userByLogin != null) {
                searchObject = TagCore.getTag(null, userByLogin, catalog, null, null);
                lbTotal.setValue(String.valueOf(searchObject.size()));
            }
            renderer = new AddTagHotFixRenderer(chkAll, gridTag);
            generateRenderer(gridTag, renderer, searchObject);
        } else {
            lbTotal.setValue(String.valueOf(list.size()));
            renderer = new AddTagHotFixRenderer(chkAll, gridTag);
            generateRenderer(gridTag, renderer, list);
        }
    }

    private void generateRenderer(Grid grid, RowRenderer renderer, List<Tag> model) {
        grid.setRowRenderer(renderer);
        if (model != null) {
            grid.setModel(new ListModelList<Tag>(model));
        }
    }
}
